#include <stdlib.h>
#include "List.h"

List* list_new(void)
{
  return NULL;
}

void list_free(List* list)
{
  List *item = list;
  List *current = NULL;

  while (item) {
    current = item;
    item = item->next;
    free(current);
  }
}

List* list_clear(List* list)
{
  list_free(list);
  return NULL;
}

List* list_append(List* list, void* data)
{
  List* item = (List*)calloc(sizeof(List), 0);
  item->data = data;

  if (list == NULL)
    return item;

  List *last = list_get_last(list);
  item->prev = last;
  last->next = item;

  return list;
}

List* list_remove(List* list, List* needle)
{
  List* item = list;
  list       = NULL;
  while (item != NULL) {
    if (item != needle) {
      item = item->next;
      continue;
    }

    /* No other items there? Then return a zero pointer. */
    if (item->prev == NULL && item->next == NULL) {
      free(item);
      return (NULL);
    }

    /* Remove the first item of the list here... */
    if (item->prev == NULL) {
      list = item->next;
      list->prev = NULL;
      free(item);
      break;
    }

    /* ...remove the last item of the list here... */
    if (item->next == NULL) {
      list = item->prev;
      item->prev->next = NULL;
      free(item);
      break;
    }

    /* ...or other items here. */
    list = item->prev;
    item->prev->next = item->next;
    item->next->prev = item->prev;
    free(item);
    break;
  }

  return list;
}

List* list_remove_data(List* list, void* data)
{
  List* item = NULL;
  while ((item = list_find_data(list, data)))
    list = list_remove(list, item);
  return list;
}

List* list_find_data(List* list, void* data)
{
  while (list != NULL && list->data != data)
    list = list->next;
  return list;
}

int list_length(List* list)
{
  int i = 0;

  if (list == NULL)
    return 0;

  while (list) {
    ++i;
    list = list->next;
  }

  return i;
}

List* list_get_first(List* list)
{
  while (list != NULL && list->prev != NULL)
    list = list->prev;
  return list;
}

List* list_get_last(List* list)
{
  while (list != NULL && list->next != NULL)
    list = list->next;
  return list;
}
